package edu.pku.sei.mte.transformation.expression;

import edu.pku.sei.mte.modification.command.ModelModificationCommand;
import edu.pku.sei.mte.mtemodel.model.MAttribute;
import edu.pku.sei.mte.mtemodel.mtmodel.expression.BindExpression;
import edu.pku.sei.mte.mtemodel.mtmodel.rulebased.Rule;
import edu.pku.sei.mte.runtime.rulebased.RBTContext;
import edu.pku.sei.mte.transformation.ModelTransformationVisitor;
import edu.pku.sei.mte.transformation.VisitorFactory;

public class EnforceExpressionVisitor extends EvaluateExpressionVisitor {

	public EnforceExpressionVisitor(RBTContext context) {
		super(context);
	}

	public EnforceExpressionVisitor(RBTContext context, Object expectedValue) {
		super(context, expectedValue);
	}

	protected void enforceBindExpression(Object expectedValue, MAttribute attr) throws Exception {
		Object oldValue = attr.getValue();
		
/*		if(env.isAttributeBinded(attr)&&BindExpression.isEqual(oldValue,expectedValue)){
			MultiValueBindingsException ex = new MultiValueBindingsException();
			ex.setContext(getContext());
			ex.setAttribute(attr);
			ex.setOldValue(oldValue);
			ex.setNewValue(expectedValue);
			ex.setReturnValue(MDAConstant.ERROR_VALUE);//default
			env.getExhandler().catchSemanticException(ex);
		} else {
			attr.setValue(expectedValue);
		}
*/		
		if(!BindExpression.isEqual(oldValue,expectedValue)){
			ModelModificationCommand.updateNodeRequest(attr, oldValue, expectedValue, getContext());
		}
	}
	
	protected boolean isCheckOnly(){
		return false;
	}
	
	protected boolean isEnforce(){
		return true;
	}
	
	protected Object enforceCallRelationExpression(Rule rule, RBTContext cc) throws Exception {
		ModelTransformationVisitor visitor = getContext().getEnvironment().getMtVisitor();
		visitor.getContextStack().push(cc);
		Object flag = rule.accept(visitor);
		visitor.getContextStack().pop();
		return flag;
	}

	@Override
	protected EvaluateExpressionVisitor getSameTypeVisitor(RBTContext context) {
		return VisitorFactory.INSTANCE.getEnforceExpressionVisitor(context);
	}

	@Override
	protected EvaluateExpressionVisitor getSameTypeVisitor(RBTContext context,
			Object expectedValue) {
		return VisitorFactory.INSTANCE.getEnforceExpressionVisitor(context, expectedValue);
	}
}
